import pandas as pd
import os
import datetime
import requests
import json
from utils import read_sql
from utils import df_into_db


DATA_DIR = 'E:\\data'
OHLCVM_DATA_DIR = os.path.join(DATA_DIR, 'ohlcvm_data')

def filter_coins_not_updated_over_1year():
    df = read_sql("select * from coins_not_updated_over_1year", db_name="all_history_ohlcvm_coinmarketcap")
    return df["slug"].tolist()

    ohlcvm_folder = 'E:\\data\\ohlcvm_data\\daily'
    today = datetime.datetime.now()
    flag_date = (today - datetime.timedelta(days=380)).strftime('%Y-%m-%d')
    coins_list = []
    for file in os.listdir(ohlcvm_folder):
        df = pd.read_csv(os.path.join(ohlcvm_folder, file))
        if len(df) == 0:
            continue
        if df['end_date'].iloc[-1] < flag_date:
            coins_list.append(file.split('.')[0])
    return coins_list


def get_daily_ohlcvm_by_id_via_http(id=None, **kwargs):
    print(f'开始获取id={id}的所有OHLCVM数据')
    range = kwargs.pop('range', 'ALL')

    header = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'}
    url = f'https://api.coinmarketcap.com/data-api/v3/cryptocurrency/detail/chart?id={id}&range={range}'
    a = requests.get(url, headers=header, timeout=5)
    res = json.loads(a.text)
    if 'data' not in res.keys():
        print(f'id={id}的数据无法获取, 提示{res["status"]}')
        return pd.DataFrame()
    elif a.status_code == 200 and len(res['data']) == 0:
        print(f'id={id}的数据为空无法获取')
        return pd.DataFrame()
    res_list = []
    for item in res['data']['points']:
        res_list.append([item] + res['data']['points'][item]['v'])
    df = pd.DataFrame(res_list, columns=['time_stamp', 'close', 'amount', 'market_cap', 'price_in_btc', 'circulating_supply'])
    df['circulating_supply'] = df['circulating_supply'] / df['price_in_btc']
    df['volume'] = df['amount'] / (df['close'])
    df['end_date'] = pd.to_datetime(df['time_stamp'], unit='s').dt.tz_localize('UTC').dt.tz_convert('+0000')
    df['end_date'] = df['end_date'].dt.strftime('%Y-%m-%d')
    df['datetime'] = pd.to_datetime(df['time_stamp'], unit='s').dt.tz_localize('UTC').dt.tz_convert('+0000')
    df['datetime'] = df['datetime'].dt.strftime('%Y-%m-%d %H:%M:%S')
    df.sort_values(by=['datetime'], inplace=True)

    df = df.groupby('end_date')[['time_stamp', 'close', 'market_cap', 'price_in_btc', 'circulating_supply', 'datetime','amount', 'volume']].last()
    today = datetime.datetime.now().strftime('%Y-%m-%d')
    df = df[df.index != today]
    print(f'id={id}的所有OHLCVM数据获取成功')
    return df

def update_daily_ohlcvm_one_coin(coin_info):
    # 指定币的日行情仅能更新一年以内的。
    coin_id = coin_info[0]
    coin_name = coin_info[1]
    # print(f'获取{coin_name}行情数据')
    file_name = os.path.join(OHLCVM_DATA_DIR, f'daily\\{coin_name}.csv')
    yesterday = (datetime.datetime.now() - datetime.timedelta(days=1)).strftime('%Y-%m-%d')
    if os.path.exists(file_name):
        historical_df = pd.read_csv(file_name, index_col='end_date')
        if not historical_df.empty:
            last_update = historical_df.index[-1]
        else:
            historical_df = pd.DataFrame()
            last_update = '2010-01-01'
    else:
        historical_df = pd.DataFrame()
        last_update = '2010-01-01'
    if last_update == yesterday:
        return
    update = get_daily_ohlcvm_by_id_via_http(coin_id, range='1Y')
    if update.empty:
        return
    if len(update) < 360:
        df = update
    elif update.index[0] <= last_update < update.index[-1]:
        df = pd.concat([historical_df[:-1], update[last_update:]], axis=0)
    elif update.index[0] > last_update:
        # print(f'{coin_name}行情数据超过一年未更新，需调用其他api')
        return
    else:
        df = historical_df
    df = df.reset_index(drop=False)
    df['symbol'] = coin_name
    df.fillna(0, inplace=True)
    df_into_db(df, db_name="all_history_ohlcvm_coinmarketcap", table_name="ohlcvm_daily")

# 并行更新所有币的行情数据
print('开始更新所有币的行情数据')

coins = pd.read_csv(os.path.join(DATA_DIR, 'coins_information\\coins_information.csv'))
coins_not_updating = filter_coins_not_updated_over_1year()
coins['updated_nearly'] = [True if i not in coins_not_updating else False for i in coins['slug']]
coins_available = coins[(coins['status'] != 'untracked') & (coins['updated_nearly'] == True)]
coin_info_list = list(zip(coins_available['id'], coins_available['slug']))
# cpu_num = psutil.cpu_count(logical=True)
# p = Pool(int(cpu_num * 0.8))
# p.map(update_daily_ohlcvm_one_coin, coin_info_list)
# p.close()
# p.join()
coin_info_list = coin_info_list[1:100]
exist_df = read_sql("select distinct `symbol` from ohlcvm_daily", db_name="all_history_ohlcvm_coinmarketcap")
for coin_info in coin_info_list:
    if coin_info[1] in set(exist_df['symbol']):
        continue
    update_daily_ohlcvm_one_coin(coin_info)